package org.net.loader
{
	import flash.display.MovieClip;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	import org.utils.DictionaryUtil;
	
	public class ResManager extends EventDispatcher
	{	
		/**
		 *单例 
		 */
		private static var _instance:ResManager
		
		private static var _list : Array = new Array;
		
		private static var _wait : Dictionary = new Dictionary(true);
		private static var _loaded : Dictionary = new Dictionary(true);
		
		private var _model : LoadModel;
		
		public static function get instance() : ResManager{
			return _instance || (_instance=new ResManager(new Singleton()))
		}
		
		public function ResManager(singleton:Singleton){
			_model = new LoadModel();
		}
		
		
		/**
		 * 加入加载器
		 * 
		 * @param loader 加载器
		 */
		public function add(loader : ALoader) : void {
			var key : String = loader.key;
			
			if (loader.isLoaded) {
				_loaded[key] = loader;
				return;
			}
			
			//key must be unique
			if (_loaded[key] != null) {
				throw new Error("a duplicate key in _loaded: " + key);
			}
			if (_wait[key] != null) {
				throw new Error("a duplicate key in _wait: " + key);
			}
			
			_list.push(loader);
			_wait[key] = loader;
		}
		
		/**
		 * load
		 */
		public function load() : void {
			if (_list.length == 0) {
				_model.end();
				dispatchEvent(new Event(Event.COMPLETE));
				return;
			}
			_model.reset(_list.length);
			loadNext();
		}
		
		
		private function loadNext() : void {
			var loader : ALoader;
			while (_model.hasFree()) {
				if (_list.length == 0)
					return;
				loader = ALoader(_list.shift());
				_model.add(loader.loadProgress);
				loader.addEventListener(Event.COMPLETE, completeHandler);
				loader.addEventListener(ErrorEvent.ERROR, errorHandler);
				loader.load();
			}
		}
		
		
		private function completeHandler(event : Event) : void {
			var loader : ALoader = ALoader(event.target);
			loader.removeEventListener(Event.COMPLETE, completeHandler);
			loader.removeEventListener(ErrorEvent.ERROR, errorHandler);
			_model.remove(loader.loadProgress)
			delete _wait[loader.key];
			_loaded[loader.key] = loader;
			if (_list.length > 0) {
				loadNext();
			} else if(DictionaryUtil.isEmpty(_wait)){
				_model.end();
				trace("RESManager load all done");
				dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		
		private function errorHandler(event : ErrorEvent) : void {
			var loader : ALoader = ALoader(event.target);
			loader.removeEventListener(Event.COMPLETE, completeHandler);
			loader.removeEventListener(ErrorEvent.ERROR, errorHandler);
			_model.remove(loader.loadProgress)
			trace("load error");
			delete _wait[loader.key];
			_loaded[loader.key] = loader;
			if (_list.length > 0) {
				loadNext();
			} else if(DictionaryUtil.isEmpty(_wait)){
				_model.end();
				dispatchEvent(new Event(Event.COMPLETE));
			}
		}
		
		
		/**
		 * getMovieClip
		 * 
		 * @param key
		 * @param className
		 * @return MovieClip
		 * @see org.net.loader.SwfLoader.getMovieClip()
		 */
		public function getMovieClip(key : String, className : String) : MovieClip {
			var loader : SwfLoader = _loaded[key] as SwfLoader;
			if (loader == null) {
				return null;
			}
			return loader.getMovieClip(className);
		}
		
		
		/**
		 * 获得加载模型
		 * 
		 * @return 加载模型
		 */
		public function get model() : LoadModel {
			return _model;
		}
	}
}


class Singleton{}